home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-17 | 4.6 KB | 123 lines | [TEXT/CCL2] |
- (in-package :cl-user)
-
- ;;; Read-eval-inspect
- ;;; Michael Travers 5/91
- ;;; thanks to Henry Lieberman for original idea
-
- #|
- This does two things: 1) results from the Listener get brought into a special inspector window
- (you can control what classes of objects get this treatment). 2) The variable % will always
- be equal to the object in the topmost inspector.
-
- You should also know about Option-clicking on lines within inspectors. Try it.
-
- Todo:
- - if item is already in an inspect window, just update it and bring it front
-
- |#
-
-
- (defmethod inspect-new-thing ((w inspector::inspector-window) thing)
- (catch :cancel
- (inspector::install-new-inspector (view-container (inspector::inspector-view w) )
- (inspector::make-inspector thing))
- (set-window-layer w (1+ *windoid-count*))))
-
-
- (defvar *readloop-inspector* nil)
-
- ;;; Access through this function to ensure the inspect window remains valid
- (defun readloop-inspector ()
- (if (and *readloop-inspector*
- (slot-value *readloop-inspector* 'wptr))
- *readloop-inspector*
- (multiple-value-bind (pos size) (inspector-position-and-size)
- (setq *readloop-inspector*
- (make-instance 'inspector::inspector-window
- :inspector (make-instance 'inspector::usual-inspector
- :object "Welcome to read-eval-inspect")
- :view-position pos
- :view-size size))
- ;; Init arg doesn't work.
- (set-view-size *readloop-inspector* size)
- *readloop-inspector*)))
-
- (defun inspector-position-and-size ()
- (let* ((l-position (view-position *top-listener*))
- (l-size (view-size *top-listener*)))
- (values (+ l-position (point-h l-size))
- (make-point (- *screen-width* (+ (point-h l-position) (point-h l-size)))
- (point-v l-size)))))
-
- ;;; Refinement - only inspect some classes
-
- ;;; To be displayed, an object must be a subclass of some yes class, and also not be
- ;;; a subclass of all no classes. Got that? Either the yes or no class list can be
- ;;; nil in which case the check isn't done.
-
- ;;; Theory behind these values is we want to see anything with structure not obvious from
- ;;; its printed representation, but not every method def because they usually aren't interesting.
- (defparameter *readloop-inspector-yes-classes* '(standard-object structure macptr cons array))
- (defparameter *readloop-inspector-no-classes* '(standard-method string))
-
- ;;; Menu control
-
- (defvar *readloop-inspector-on* t)
-
- (defvar *readloop-inspect-menu-item*
- (let ((it (make-instance 'menu-item
- :menu-item-title "Auto Inspect"
- :menu-item-action 'readloop-inspect-toggle)))
- (add-menu-items *eval-menu*
- (make-instance 'menu-item :menu-item-title "-" :disabled t)
- it)
- (set-menu-item-check-mark it *readloop-inspector-on*)
- it))
-
- (defun readloop-inspect-toggle ()
- (setq *readloop-inspector-on* (not *readloop-inspector-on*))
- (set-menu-item-check-mark *readloop-inspect-menu-item* *readloop-inspector-on*))
-
-
- (defun maybe-inspect-new-thing (thing)
- (when (and *readloop-inspector-on*
- (and (or (null *readloop-inspector-yes-classes*)
- ;; I wonder if this is actually guaranteed valid in CL...
- (find thing *readloop-inspector-yes-classes* :test #'typep))
- (or (null *readloop-inspector-no-classes*)
- (not (find thing *readloop-inspector-no-classes* :test #'typep)))))
- (inspect-new-thing (readloop-inspector) thing)))
-
- ;;; Perhaps this could use evalhook instead of relying on an unadvertised function.
- (ccl:advise ccl::toplevel-eval
- (progn
- (without-interrupts
- (maybe-inspect-new-thing (caar values))))
- :when :after :name :read-eval-inspect)
-
- ;;; % feature
- ;;; separable from read-eval-inspect, actually
- (defvar ccl::% nil "The value in the top inspect window.")
-
- (export 'ccl::% :ccl)
-
- (defmethod window-select :after ((w inspector::inspector-window))
- (setq ccl::% (inspector::inspector-object w)))
-
- (advise inspector::push-inspector-history
- (setq ccl::% (top-inspect-form))
- :when :after :name set-%)
-
- ;;; First impressions are so important
- (eval-when (eval load)
- (setq ccl::% (top-inspect-form)))
-
- ;;; new: update inspect history automatically
- (advise inspector::push-inspector-history
- (let ((ihw (find-window "inspector history")))
- (when ihw
- (inspector::resample ihw)))
- :when :after :name update-history-window)
-
- (provide :read-eval-inspect)
-